<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <!-- 
    生命周期图谱：
      https://v2.cn.vuejs.org/v2/guide/instance.html#%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E5%9B%BE%E7%A4%BA

   -->

    <div id="app">
      <h1>Vue2 生命周期</h1>
      <p>{{ msg }}</p>
      <button @click="msg += '~'">修改数据</button>

      <button @click="$destroy()">销毁</button>
    </div>

    <script src="../lib/vue2.js"></script>

    <script>
      new Vue({
        el: "#app",

        // 如果设置了,就以这个为准
        // 如果没有设置,就以挂载点的内容为准
        // template: `
        //   <div>
        //     <h2>我是 template 选项设置的</h2>  
        //     <p>{{ msg }}</p>
        //   </div>
        // `,

        // 如果设置了 render 函数,则以他为准
        // 否则,Vue会将 template 的内容编译成 render 函数
        // render(createElement) {
        //   // Vue2 的 render 函数，会接受到一个 createElemnet 的参数，该参数就相当于 Vue3 中的 h 函数

        //   return createElement('button', null, '按钮')
        // },

        data: {
          msg: "hello",
        },

        computed: {
          reverseMsg() {
            return this.msg.split("").reverse().join("");
          },
        },

        methods: {
          say() {
            console.log("say");
          },
        },
        // 创建之前
        //    1. 响应式数据还没有代理到实例（this）上，不能访问到 data、computed、methods 中定义的内容
        //    2. 一般用不上，唯一的操作就是想要初始化一些数据到实例上
        beforeCreate() {
          console.log("=== beforeCreate");
          console.log(this.msg); // undefined
          console.log(this.reverseMsg); // undefined
          console.log(this.say); // undefined

          // setTimeout(() => {
          // this.abcd = "abcd";
          // })
        },

        // 创建完成
        //    1. 从这个钩子开始，数据代理已经完成，可以通过 this 访问到 data computed methods 中定义的内容了。
        //    2. 应用场景：
        //        1. 调用接口,获取数据
        created() {
          console.log("=== created");
          console.log(this.abcd); // undefined
          console.log(this.msg); // hello
          console.log(this.reverseMsg); // olleh
          console.log(this.say); // function() {}
        },

        // 挂载之前
        //    1. 能否获取到 $el 这个实例属性, 可以的
        //    2. $el 里面的内容有没有被数据替换掉(是不是经过Vue处理之后的DOM)  不行的
        beforeMount() {
          console.log('=== beforeMount')
          console.log(this.$el.innerHTML) // 有 {{ msg }}

          // 在这儿直接修改DOM,页面会修改掉,但是后面会经过Vue内部的重新替换
          // this.$el.innerHTML = '我的天'
        },

        // 挂载完成
        //    1. 初次使用数据与模板进行编译生成虚拟DOM,然后映射到真实DOM上.
        //    2. 从这里开始,可以获取到真实的DOM数据
        //    3. 所有对DOM的操作,都需要在挂载完成之后再去操作,否则会有问题
        mounted() {
          console.log('=== mounted')
          console.log(this.$el.innerHTML)  // 没有 {{ msg }}

          // this.$el.innerHTML = '我的天'
        },

        // 更新之前
        //    1. 这时DOM是最新的嘛 不是
        beforeUpdate() {
          console.log('=== beforeUpdate')
          console.log(document.getElementById('app').innerHTML)
        },

        // 更新完成
        //    1. 这时DOM才是最新的
        updated() {
          console.log('=== updated')
          console.log(document.getElementById('app').innerHTML)
        },

        // 销毁之前
        //    1. 在 Vue2 的时候，可以调用 $destroy() 来销毁，但是该方法在 Vue3 移除了。
        //    2. 对于子组件来说，通过 v-if 也可以控制该子组件的销毁
        //    3. 应用场景：
        //        1. 做一些清理收尾的工作
        //              全局的事件绑定、定时器、订阅的消息
        beforeDestroy() {
          console.log('=== beforeDestroy')
        },

        // 销毁完成
        //    1. 也是做收尾的工作
        //    2. 这时绑定的事件还是响应式数据都卸载了，
        destroyed() {
          console.log('=== destroyed')
        }
      });
    </script>
  </body>
</html>
